<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { ElMessage, ElTree } from 'element-plus';
import type { TreeNodeData } from 'element-plus/es/components/tree/src/tree.type';
import { systemManageApi } from '@/service/api';
import { useBoolean } from '@/hooks';

defineOptions({
  name: 'DhkPermissionDialog'
});

interface Props {
  visible: boolean;
  roleId: number;
}

const props = defineProps<Props>();

const emit = defineEmits(['update:visible', 'close', 'success']);

const { bool: loading, setTrue: startLoading, setFalse: stopLoading } = useBoolean(false);
const { bool: fetchError, setTrue: setFetchError, setFalse: clearFetchError } = useBoolean(false);
const permissionTree = ref<TreeNodeData[]>([]);
const checkedIds = ref<number[]>([]);
const treeRef = ref<InstanceType<typeof ElTree>>();

const show = computed({
  get: () => props.visible,
  set: value => {
    emit('update:visible', value);
    if (!value) {
      emit('close');
    }
  }
});

watch(() => props.visible, value => {
  if (value && props.roleId) {
    clearFetchError();
    loadPermissionWithRoleId();
  }
});

async function loadPermissionWithRoleId() {
  if (!props.roleId) return;
  
  try {
    startLoading();
    clearFetchError();
    const [treeData, checkedIdsData] = await Promise.all([
      systemManageApi.menu.fetchAllMenu(),
      systemManageApi.menu.queryPermissionIdsWithRoleId(props.roleId)
    ]);
    
    // Ensure data is always in array format
    permissionTree.value = Array.isArray(treeData) ? treeData : [];
    checkedIds.value = Array.isArray(checkedIdsData) ? checkedIdsData : [];
    
    // Set checked keys after tree is rendered
    setTimeout(() => {
      if (treeRef.value) {
        treeRef.value.setCheckedKeys(checkedIds.value);
      }
    }, 100);
  } catch (error) {
    console.error('Failed to load permission data:', error);
    setFetchError();
  } finally {
    stopLoading();
  }
}

function retryLoad() {
  loadPermissionWithRoleId();
}

function handleCancel() {
  show.value = false;
}

async function handleConfirm() {
  if (!props.roleId) {
    ElMessage.warning('角色ID不能为空');
    return;
  }

  if (!treeRef.value) {
    ElMessage.warning('权限树未初始化');
    return;
  }

  try {
    startLoading();
    const checkedKeys = treeRef.value.getCheckedKeys(false) as number[];
    const halfCheckedKeys = treeRef.value.getHalfCheckedKeys() as number[];
    const allCheckedKeys = [...checkedKeys, ...halfCheckedKeys];
    
    // Validation
    if (!Array.isArray(allCheckedKeys)) {
      ElMessage.warning('获取选中权限失败');
      return;
    }

    await systemManageApi.menu.add({
      roleId: props.roleId,
      permissionIds: allCheckedKeys
    });
    
    ElMessage.success('保存成功');
    show.value = false;
    emit('success');
  } catch (error) {
    console.error('Failed to save permissions:', error);
    ElMessage.error('保存失败');
  } finally {
    stopLoading();
  }
}

function getNodeKey(node: TreeNodeData) {
  return node.id as number;
}
</script>

<template>
  <el-dialog
    v-model="show"
    title="菜单权限配置"
    width="70%"
    destroy-on-close
    :close-on-click-modal="false"
  >
    <div class="h-[60vh] overflow-auto">
      <div v-if="fetchError" class="flex-col-center h-full">
        <el-empty description="数据加载失败">
          <el-button type="primary" @click="retryLoad">重试</el-button>
        </el-empty>
      </div>
      <div v-else class="permission-tree-container">
        <el-tree
          ref="treeRef"
          :data="permissionTree"
          :props="{
            label: 'title',
            children: 'children'
          }"
          show-checkbox
          default-expand-all
          node-key="id"
          :check-strictly="false"
        />
      </div>
    </div>
    <template #footer>
      <el-button @click="handleCancel">取消</el-button>
      <el-button
        type="primary"
        :loading="loading"
        @click="handleConfirm"
      >
        确认
      </el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.permission-tree-container {
  padding: 16px;
  border-radius: 4px;
  background-color: var(--el-bg-color);
}

:deep(.el-tree) {
  background-color: transparent;
}

:deep(.el-tree-node__content) {
  height: 40px;
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: var(--el-color-primary-light-9);
}
</style> 